﻿using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Yb
{
    public sealed class SecureBool : IDisposable
    {
        private byte[] _encryptedValue;
        private byte[] _key;
        private byte[] _iv;
        private bool _isDisposed = false;
        private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();

        // 导入Windows API用于反调试
        [DllImport("kernel32.dll")]
        private static extern bool IsDebuggerPresent();

        [DllImport("kernel32.dll")]
        private static extern void OutputDebugString(string str);

        public SecureBool(bool initialValue)
        {
            Initialize(initialValue);
        }

        private void Initialize(bool value)
        {
            // 检测调试器
#if RELEASE && !DEBUG
            AntiDebugCheck();
#endif
            GenerateNewKeys(); // 生成初始密钥

            // 将布尔值转换为字节
            byte[] valueBytes = BitConverter.GetBytes(value);
            _encryptedValue = Encrypt(valueBytes, _key, _iv);

            // 立即清除明文字节数组
            Array.Clear(valueBytes, 0, valueBytes.Length);

            // 在内存中混淆
            ObfuscateMemory();
        }

        public bool Value
        {
            get
            {
                if (_isDisposed)
                    throw new ObjectDisposedException("SecureBool");

                AntiDebugCheck();
                AntiMemoryScan();

                byte[] decrypted = Decrypt(_encryptedValue, _key, _iv);
                bool result = BitConverter.ToBoolean(decrypted, 0);

                // 立即清除解密后的数组
                Array.Clear(decrypted, 0, decrypted.Length);

                return result;
            }
            set
            {
                if (_isDisposed)
                    throw new ObjectDisposedException("SecureBool");

                AntiDebugCheck();

                // 生成新密钥（每次设置都使用新密钥）
                GenerateNewKeys();

                byte[] valueBytes = BitConverter.GetBytes(value);
                byte[] newEncrypted = Encrypt(valueBytes, _key, _iv);

                // 更新加密值
                if (_encryptedValue != null)
                    Array.Clear(_encryptedValue, 0, _encryptedValue.Length);

                _encryptedValue = newEncrypted;

                // 清除明文字节数组
                Array.Clear(valueBytes, 0, valueBytes.Length);

                // 重新混淆内存
                ObfuscateMemory();
            }
        }

        // 生成新密钥方法
        private void GenerateNewKeys()
        {
            using (var aes = Aes.Create())
            {
                aes.GenerateKey();
                aes.GenerateIV();

                // 安全清除旧密钥
                if (_key != null)
                    Array.Clear(_key, 0, _key.Length);
                if (_iv != null)
                    Array.Clear(_iv, 0, _iv.Length);

                // 分配新密钥
                _key = new byte[aes.Key.Length];
                _iv = new byte[aes.IV.Length];

                Array.Copy(aes.Key, _key, aes.Key.Length);
                Array.Copy(aes.IV, _iv, aes.IV.Length);
            }
        }

        private byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
        {
            using (var aes = Aes.Create())
            {
                aes.Key = key;
                aes.IV = iv;
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.PKCS7;

                using (var encryptor = aes.CreateEncryptor())
                {
                    return encryptor.TransformFinalBlock(data, 0, data.Length);
                }
            }
        }

        private byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
        {
            using (var aes = Aes.Create())
            {
                aes.Key = key;
                aes.IV = iv;
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.PKCS7;

                using (var decryptor = aes.CreateDecryptor())
                {
                    return decryptor.TransformFinalBlock(data, 0, data.Length);
                }
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
        private void ObfuscateMemory()
        {
            // 内存混淆：在内存中散布虚假数据
            byte[] dummyData1 = new byte[16];
            byte[] dummyData2 = new byte[32];

            _rng.GetBytes(dummyData1);
            _rng.GetBytes(dummyData2);

            // 故意使用这些数据但不做任何事情
            _ = dummyData1.Length + dummyData2.Length;

            // 快速清除虚假数据
            Array.Clear(dummyData1, 0, dummyData1.Length);
            Array.Clear(dummyData2, 0, dummyData2.Length);
        }

        private void AntiDebugCheck()
        {
#if RELEASE && !DEBUG
    if (IsDebuggerPresent())
    {
        OutputDebugString("Debugger detected - secure variable protection triggered");
        ThrowSecurityException();
    }
#endif
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private void AntiMemoryScan()
        {
            // 随机延迟，增加内存扫描难度
            var random = new Random(Guid.NewGuid().GetHashCode());
            if (random.Next(100) < 5) // 5% 的概率引入微小延迟
            {
                System.Threading.Thread.Sleep(1);
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private void ThrowSecurityException()
        {
            // 抛出难以追踪的安全异常
            throw new SecurityException("Secure variable access violation detected");
        }

        public void Dispose()
        {
            if (!_isDisposed)
            {
                // 安全清除所有敏感数据
                if (_encryptedValue != null)
                    Array.Clear(_encryptedValue, 0, _encryptedValue.Length);

                if (_key != null)
                    Array.Clear(_key, 0, _key.Length);

                if (_iv != null)
                    Array.Clear(_iv, 0, _iv.Length);

                _isDisposed = true;
                GC.SuppressFinalize(this);
            }
        }

        ~SecureBool()
        {
            Dispose();
        }

        public override bool Equals(object obj)
        {
            throw new SecurityException("Secure variables cannot be compared directly");
        }

        public override int GetHashCode()
        {
            throw new SecurityException("Secure variables cannot be hashed");
        }
    }

    public class SecurityException : Exception
    {
        public SecurityException(string message) : base(message) { }
    }
}